#pragma once

#include <entt/entt.hpp>
#include "./bundle.hpp"
#include "./world.hpp"

namespace qbe::ecs {

class Commands {
 private:
  World& _world;

 public:
  Commands(World& world) : _world(world){};

  template <typename... Args>
  entt::entity spawn(const Args&... args) {
    // auto e = _world.get_registry().create();
    // (_world.get_registry().emplace<Args>(e, args), ...);
    return _world.spawn(std::forward<Args>(args)...);
  }

  template <typename... Args>
  entt::entity spawn(const Bundle<Args...>& bundle) {
    return bundle.create_entity(_world.get_registry());
  }

  template <typename... Args>
  void remove(const entt::entity& entity) {
    (_world.get_registry().remove<Args>(entity), ...);
  }

  void destory(const entt::entity& entity) { _world.get_registry().destroy(entity); }

  // Resource
  template <typename R>
  void insert_resource(const R& value) {
    _world.insert_resource(value);
  }

  template <typename... Args>
  void insert_resources(Args&&... args) {
    (insert_resource(args), ...);
  }

  template <typename R>
  std::optional<R> remove_resource() {
    return _world.remove_resource<R>();
  }

  // Compoent
  template <typename T>
  void insert_component(entt::entity e, T&& component) {
    _world.get_registry().emplace<T>(e, std::forward<T>(component));
  }

  template <typename T>
  void remove_component(entt::entity e, T&& component) {
    _world.get_registry().remove<T>(e);
  }
};

}  // namespace qbe::ecs